import urllib

import talib
from django.core.serializers import serialize
from django.db.models import QuerySet, Count
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from wx.lib.agw.shortcuteditor import DATA_DIR

from chartstest.datasViews import connectushare
from .models import *
import os, json
import pandas as pd
from pylab import *
import tushare as ts
from django.core import serializers


# Create your views here.
def macdIndex(request):
    data_list = []
    # query = TusharDate.objects.all().query
    # query.group_by = ['tscode']
    # book_list = QuerySet(query=query, model=TusharDate)
    #tscode 分组
    result = TusharDate.objects.values('tscode').annotate(Count=Count('tscode')).order_by('-id')[:3]
    # print(type(result))
    #print(result.count())

    for obj in result:
        # print(obj)
        data_list.append(obj)

    # for i in range(0, len(book_list)):
    #     #data_list.append(book_list[i][9])
    #     print(i)
    # print(book_list.count())

    # print("json:" + json.dumps(data_list))
    # print(data_list)

    # return render(request, 'chartstest/public.html', {"dataList": data_list})
    return render(request, 'chartstest/macdIndex.html', {"dataList": json.dumps(data_list, ensure_ascii=False)})

    # 以下为查询，有专用的方式，比如
    # 实现where子名，作为方法filter()、exclude()、get()的参数
    # 语法：属性名称__比较运算符=值
    # 表示两个下划线，左侧是属性名称，右侧是比较类型
    # 对于外键，使用“属性名_id”表示外键的原始值
    # 转义：like语句中使用了%与，匹配数据中的%与，在过滤器中直接写，例如：filter(title__contains="%")=>where title like '%\%%'，表示查找标题中包含%的

    # 返回列表
    # list  = BookInfo.books1.filter(heroinfo__hcontent__contains="六")    # 包含 六 的书
    # 等价于 select * from bookinfo inner join booktest_heroinfo on bookinfo.id=book_id;
    # 是查 heroinfo 的 hcontent 中包含 六 的英雄对应的书 （BookInfo）
    # list = BookInfo.books1.aggregate(Max('id'))
    # context = {'list': list}
    # return render(request, 'booktest/public.html', context)

    # list = BookInfo.books1.filter(pk__lt=3).

    # context = {'list': list}
    # return render(request, 'booktest/public.html', context)

    # 使用aggregate()函数返回聚合函数的值
    # 函数：Avg，Count，Max，Min，Sum
    # Max1 = BookInfo.books1.aggregate(Max('id'))           # id 的最大值
    # Max1 = BookInfo.books1.aggregate(Max('bpub_data'))      # bpub_data 的最大值
    # Max1 = BookInfo.books1.aggregate(Sum('id'))
    #
    #
    # list1 = BookInfo.books1.filter(bread__gt=10)            # 阅读量大于10
    #
    #
    # # 两个列做自己算使用 F 对象，列比较，列计算等
    # list1 = BookInfo.books1.filter(bread__gt=F('bcommet'))  # 阅读量大于评论量
    #
    #
    # # 逻辑与关系
    # list1 = BookInfo.books1.filter(pk__lt=4, btitle__contains='1')
    # list1 = BookInfo.books1.filter(pk__lt=4).filter(btitle__contains='1')
    #
    # # 逻辑或使用 Q 对象
    #
    # list1 = BookInfo.books1.filter(( Q(pk__lt=6) | Q(bcommet__gt=10) ))
    # context = {'list1': list1
    #             , 'Max1': Max1
    #            }
    # return render(request, 'booktest/public.html', context)


# 在处理函数加此装饰器即可
@csrf_exempt
def jsonDate(request):
    tscode = request.POST['tscode']
    tusharDates = TusharDate.objects.filter(tscode=tscode)
    # print(tusharDates)

    # ret = models.TusharDate.objects.all().order_by("dayIncome", "id")
    ret1 = serialize("json", tusharDates)
    retList = json.loads(ret1)
    # print(retList)
    ret2 = []
    print('---------------------')
    for num in range(len(retList)):
        fields = retList[num]['fields']
        fields.update(id=retList[num]['pk'])
        ret2.append(fields)
        # print(ret2)

    data = {'status': 0, 'dates': ret2}
    return HttpResponse(json.dumps(data, ensure_ascii=False), content_type="application/json,charset=utf-8")


# 计算查询结果
# 在处理函数加此装饰器即可
@csrf_exempt
def macdResult(request):
    # 参数
    tscode = request.POST['tscode']
    startTime = request.POST['startTime']
    endTime = request.POST['endTime']
    macdF = request.POST['macdF']
    macdSL = request.POST['macdSL']
    macdSI = request.POST['macdSI']
    buy = request.POST['buy']
    sell = request.POST['sell']

    ls = json.dumps(tscode, ensure_ascii=False)
    info = HttpResponse(ls)

    # 下面这两行设置夸域请求，跨域就是用这两行
    # info['Access-Control-Allow-Origin'] = '*'
    # info['Access-Control-Allow-Headers'] = "Content-Type"
    if tscode == '':
        ls = json.dumps(tscode, ensure_ascii=False)
        info = HttpResponse(ls)
        return info
    if startTime == '':
        ls = json.dumps(tscode, ensure_ascii=False)
        info = HttpResponse(ls)
        return info
    if endTime == '':
        ls = json.dumps(tscode, ensure_ascii=False)
        info = HttpResponse(ls)
        return info
    startTime = startTime.replace('-', '')
    endTime = endTime.replace('-', '')
    # print(startTime + endTime)
    # pro = ts.pro_api('09c23ca7df4d6e0692459fd98de6207c1d687158fb1e946f5be77af8')


    # 使用ggplot样式，好看些
    # mpl..style.use("ggplot")
    # 获取上证指数数据
    # data = ts.get_k_data("000001", index=True, start="2019-01-01")
    ts_code = '600575.SH'
    start_date = '20180701'
    end_date = '20191024'
    f = 12
    s = 26
    si = 9
    #
    if macdF != '':
        f = int(macdF)
    if macdSL != '':
        s = int(macdSL)

    if macdSI != '':
        si = int(macdSI)

    # print(type(macdF))
    # 从tushare查询某只股票日线数据
    #pro = connectushare
    data = connectushare().daily(ts_code=tscode, start_date=startTime, end_date=endTime)
    pd.set_option('display.max_columns', None)
    # if data is None:
    #     return info
    # 排序
    data.sort_values(by='trade_date', axis=0, ascending=True, inplace=True, na_position='first')
    print("排序------------")
    # print(data)
    # 将date值转换为datetime类型，并且设置成index
    data.trade_date = pd.to_datetime(data.trade_date)
    data.index = data.trade_date

    # print(data)
    # 周线MACD什么意思
    #
    # QR技术分析社区告诉我们周线MACD什么意思：
    #
    # 第一步：粗选出周线MACD金叉的股票，要点如下：
    # [1]
    # 在0轴金叉的股票最佳，拉升力度和幅度将最大；距离0轴较远的金叉次之。
    # [2]
    # 在0轴下方较远的金叉，预示主力处于建仓期，后市震荡洗盘难以避免。
    # [3]
    # 在0轴上放较远的金叉，预示主力已完成大幅拉升后再次产生上升势头，此时须谨防假突破被套山顶。
    #
    # 第二步：在选出周线MACD金叉的股票后，再用日线继续精选，要点如下：
    # [1]
    # 股价第一次站上60日均线最佳，太早不牢靠，太晚就追高了。
    # [2]
    # 日成交量明显放大，量比在1
    # .5
    # 以上。
    # [3]
    # 日线MACD刚刚升到0轴之上，或在0轴恰好金叉最佳。
    #
    # 第三步：把符合以上条件的股票精选出来后，组成自选股股票池，到周一跟踪观察。
    #
    # 第四步：盘中跟踪与买进要点：
    # [1]
    # 操作的最佳时机在前后15分钟，所跟踪目标若在9点25分第一笔成交中，量比达到8以上，高开幅度在1 %—3 % 之间，则可以立即买进了。
    # [2]
    # 若大盘走势平稳，所跟踪目标中那个列热点板块排名靠前，优先考虑介入那个票。
    # [3]
    # 买进介入点利用分时图技术确定，也可以在尾盘15分钟确定。
    #
    # 在了解完MACD的特性后，投资者可以试着使用MACD金叉死叉来进行交易，QR量化社区告诉投资者们
    # MACD金叉选股公式怎么设置来进行选股。下面，我们为投资者们举例：
    # MACD金叉选股公式通达信源码：
    # 计算MACD指标数据
    # 然后按照下面的原则判断买入还是卖出。
    # 1. DIFF、DEA均为正，DIFF向上突破DEA，买入信号。
    # 2. DIFF、DEA均为负，DIFF向下跌破DEA，卖出信号。
    # 3.DEA线与K线发生背离，行情反转信号。
    # 4.分析MACD柱状线，由正变负，卖出信号；由负变正，买入信号。
    # 上面便是MACD金叉选股公式的一个变种，在MACD金叉的情况下，加入了在零轴上方首次金叉，同时收盘价在MA60之上的这两个条件。投资者们可以使用这个源码在通达信上过滤出符合条件的股票，从而进行投资。当然，投资者们也可以根据自己的思路或想法来改变这个源码，比如上例中设置成在零轴之上的MACD金叉，零轴之下的MACD金叉，第一次MACD金叉，甚至第二次MACD金叉都是可以的。
    #
    # MACD选股公式怎么设置，这是很多投资者所头疼的问题。投资者们对很多技术指标都有自己的想法，但是却不知道如何去设置改变指标。QR量化投资社区告诉我们，投资者需要先选取自己所喜爱的平台，如通达信，同花顺，大智慧，文华财经等等，因为每个平台在指标的表示上都有所不同。
    #
    # MACD选股公式怎么设置，我们以通达信举例，当选定好了平台，就可以设置指标了。通达信中的选股器可以帮助投资者做到MACD金叉选股。以下是我们使用选股器选出的目前MACD金叉时的股票。

    # macd（对应diff），
    # macdsignal（对应dea），
    # macdhist（对应macd）。
    data["DIFF"], data["DEA"], data["MACD"] = talib.MACD(data.close, fastperiod=f, slowperiod=s, signalperiod=si)
    # macd = talib.MACD(data.close)
    # print("macd:" + str(macd))

    # 计算移动平均线
    # data["ma10"] = talib.MA(data.close, timeperiod=10)
    # data["ma30"] = talib.MA(data.close, timeperiod=30)

    # 计算RSI
    # data["rsi"] = talib.RSI(data.close)

    # 计算MACD指标数据
    # data["macd"], data["sigal"], data["hist"] = talib.MACD(data.close)

    # def OnKeyTyped(self, event):
    #          print(event.GetString())

    # dataform 转成list
    train_data = np.array(data)  # np.ndarray()
    train_x_list = train_data.tolist()  # list

    # 数据排序，正序
    train_x_list.sort(key=lambda x: x[0], reverse=True)
    # print(train_x_list)
    # 买点
    bu = 0
    # 卖点
    se = 0

    #       buy,sell
    if buy != '':
        bu = int(buy)
    if sell != '':
        se = int(sell)

    total = 0
    a = 0
    b = 0
    buyPrice = 0.00
    sellPrice = 0.00
    success_ratio = 0.00
    buyTime = ""
    sellTime = ""

    dealDetailList = []
    # ts_code 股票代码 0
    # trade_date 交易日期 1
    # open 开盘价 2
    # high 最高价 3
    # low 最低价 4
    # close 收盘价 5
    # pre_close 昨收价 6
    # change 涨跌额 7
    # pct_chg 涨跌幅 8
    # vol 成交量 （手）9
    # amount 成交额 （千元） 10
    # DIFF 11
    # DEA 12
    # MACD 13
    # ma10  14
    # ma30  15
    #
    ma = 1

    if(bu > 0):
        ma = bu


    if (se > ma):
        ma = se
    print(ma)
    openPrice = 0.00
    # 获取3天的数据：开盘价，收盘价，diff，dea，
    for i in range(1, len(train_x_list) - ma):
        result = 0.00

        # 前一天的数据
        open2 = train_x_list[i - 1][2]
        DIFF2 = float(train_x_list[i - 1][11])
        DEA2 = float(train_x_list[i - 1][12])
        MACD2 = float(train_x_list[i - 1][13])
        close2 = train_x_list[i - 1][5]
        # print(train_x_list[i])

        # 当天数据
        # 开盘价
        open = train_x_list[i][2]
        close = train_x_list[i][5]
        # 均价
        avg = train_x_list[i][4]
        #
        DIFF = float(train_x_list[i][11])
        DEA = float(train_x_list[i][12])
        MACD = float(train_x_list[i][13])
        # 收盘价

        # 后一天数据
        open3 = train_x_list[i + 1][2]
        DIFF3 = float(train_x_list[i + 1][11])
        DEA3 = float(train_x_list[i + 1][12])
        MACD3 = float(train_x_list[i + 1][13])
        close3 = train_x_list[i + 1][5]

        # 有空值循环下一个
        if (DIFF2 != DIFF2):
            continue

        # 实现DIFF、DEA均为正，DIFF向上突破DEA，买入股票；
        # DIFF、DEA均为负，DIFF向下突破DEA，卖出股票
        # DIFF DEA 买点 交叉点判断，前一天数值DIFF的值大于DEA2，后一天数据DIFF小于DEA
        # 当天相等，后一天的DIFF2>DEA2,这一天作为金叉点
        # if (DIFF == DEA and DIFF3 > DEA3):
        #     # buy=open
        #     # 买入时间
        #     buyTime = train_x_list[i + bu][1]
        #     # 买入价格
        #     buyPrice = float(train_x_list[i + bu][2])
        #     #第一个买价
        #     if (openPrice == 0.00):
        #         openPrice = buyPrice
        #     print("买入开始---------------")
        #     print(
        #         "DIFF:" + str(DIFF)[0:5] + " DEA:" + str(DEA)[0:5] + " DIFF2:" + str(DIFF2)[0:5] + " DEA2:" + str(DEA2)[
        #                                                                                                       0:5])
        #     print(buyTime)
        #     print(buyPrice)
        #     print("买入结束---------------")
        #
        #     continue
        #elif (DIFF3 > DEA3 and (DIFF2 < DEA2 or DIFF == DEA)):
        # 如果当前有余额，并且DIFF、DEA均为正，DIFF向上突破DEA
        if DIFF > 0 and DEA > 0 and DIFF2 > DEA2 and DIFF3 < DEA3:
        #if (MACD2 <= 0 and MACD >= 0 and MACD3>=0):

            # buy=open
            # 买入时间
            buyTime = train_x_list[i + bu][1]
            # 买入价格
            buyPrice = float(train_x_list[i + bu][2])
            # 第一个买价
            if (openPrice == 0.00):
                openPrice = buyPrice
            # print("买点：buy" + str(buyPrice) + "第" + str(train_x_list[i + bu][1]))
            print("买入开始---------------")
            print("DIFF3:" + str(DIFF3)[0:5] + " DEA3:" + str(DEA3)[0:5] + " DIFF2:" + str(DIFF2)[0:5] + " DEA2:" + str(
                DEA2)[0:5] + "DIFF:" + str(DIFF)[0:5] + "DEA:" + str(DEA)[0:5] + "MACD:" + str(MACD)[0:5])
            print(buyTime)
            print(buyPrice)
            print("买入结束---------------")
            continue

        # DIFF DEA 卖点  交叉点判断，前一天数值DIFF的值小于DEA2，后一天数据DIFF大于DEA
        # if (DIFF == DEA and DIFF3 < DEA3):
        #     # sell=open
        #     # 卖出时间
        #     sellTime = train_x_list[i + se][1]
        #     # 卖出价格
        #     sellPrice = float(train_x_list[i + se][2])
        #     print("卖出开始---------------")
        #     print(
        #         "DIFF:" + str(DIFF)[0:5] + " DEA:" + str(DEA)[0:5] + " DIFF2:" + str(DIFF2)[0:5] + " DEA2:" + str(DEA2)[
        #                                                                                                       0:5])
        #     print(sellTime)
        #     print(sellPrice)
        #     print("卖出结束---------------")
        # 如果DIFF、DEA均为负，DIFF向下跌破DEA，并且目前有头寸
        if DIFF < 0 and DEA < 0 and DIFF2 < DEA2 and DIFF3 > DEA3:
        #if (MACD3 < 0 and MACD <= 0 and MACD2 >= 0):
            # sell=open
            # 卖出时间
            sellTime = train_x_list[i + se][1]
            # 卖出价格
            sellPrice = float(train_x_list[i + se][2])
            print("卖出开始---------------")
            print("DIFF3:" + str(DIFF3)[0:5] + " DEA3:" + str(DEA3)[0:5] + " DIFF2:" + str(DIFF2)[0:5] + " DEA2:" + str(
                DEA2)[0:5] +"DIFF:" + str(DIFF)[0:5] +"DEA:" + str(DEA)[0:5] +"MACD:" + str(MACD)[0:5])
            print(sellTime)
            print(sellPrice)
            print("卖出结束---------------")

            # 计算一次交易，清零参数
        if (buyPrice != 0.00 and sellPrice != 0.00):
            result = sellPrice - buyPrice
            if (result > 0):
                b = b + 1

            print("买入价格：" + str(buyPrice) + "买入时间：" + str(buyTime) + "卖出价格：" + str(sellPrice) + "卖出时间：" + str(
                sellTime) + "" + "盈利：" + str(result))

            a = a + 1
            # 添加交易详细信息表
            dealDetail = DealDetail()
            dealDetail.tscode = tscode
            dealDetail.buyTime = buyTime
            dealDetail.sellTime = sellTime
            dealDetail.buyPrice = buyPrice
            dealDetail.sellPrice = sellPrice
            dealDetail.tradProfit = round(result, 3)
            dealDetail.profitability = round((result/buyPrice)*100, 3)
            dealDetailList.append(dealDetail)
            # tusharDate.dealdetail_set.add(dealDetail)

            buyPrice = 0.00
            sellPrice = 0.00
            buyTime = ''
            sellTime = ''
        elif (buyPrice == 0.00 and sellPrice != 0.00):
            buyPrice = 0.00
            sellPrice = 0.00
            buyTime = ''
            sellTime = ''

        total = total + result
        if (a != 0):
            success_ratio = round((b / a) * 100, 3)



    tusharDate = TusharDate()
    tusharDate.tscode = tscode
    tusharDate.macdF = f
    tusharDate.macdSI = s
    tusharDate.macdSL = si
    tusharDate.startTime = startTime
    tusharDate.endTime = endTime
    tusharDate.buy = buy
    tusharDate.sell = sell
    tusharDate.tradProfit = round(total, 3)
    tusharDate.successRatio = success_ratio
    tusharDate.profitability = round((total/openPrice)*100, 3)

    if tusharDate:
        # print(tusharDate.successRatio)
        tusharDate.save()
        for i in range(0, len(dealDetailList)):
            dealDetail = dealDetailList[i]
            dealDetail.tusharDate_id = tusharDate.id
            dealDetail.save()


    #  将数据写入新文件
    result_list = np.array(data)
    # columns = ["ts_code", "star_date", "end_date", "macdF", "macdSl", "macdSI", "buy", "sell", "total",
    #            "success_ratio"]
    # dt = pd.DataFrame(result_list, columns=columns)
    dt = pd.DataFrame(result_list)
    # dt.to_excel("result_xlsx.xlsx", index=0)
    # dt.to_csv("result_csv.csv", index=0)
    # print(tscode)
    dt.to_csv(str(tusharDate.id) + '.csv', mode='a', header=0, index=0, float_format='%.2f')
    return info


# 详细信息
@csrf_exempt
def macdDetail(request):
    print("--------------------------------------详细信息")
    # 参数
    id = request.GET['id']
    data_list = []
    result = DealDetail.objects.filter(tusharDate_id=id)


    ret1 = serialize("json", result)
    retList = json.loads(ret1)
    #print(retList)

    for num in range(len(retList)):
        fields = retList[num]['fields']

        fields.update(id=retList[num]['pk'])
        data_list.append(fields)
        # print(ret2)

    tusharDate_id = data_list[0]['tusharDate']

    # print("tscode:" + json.dumps(tscode))

    # 读取文件数据
    data = pd.read_csv(str(tusharDate_id) + '.csv')
    train_data = np.array(data)  # np.ndarray()
    macdlist = train_data.tolist()  # list
    macdlist.sort()
    # print(macdlist)
    # print(type(macdlist))

    # ret1 = serialize("json", datelist)
    # retList = json.loads(ret1)
    # # print(retList)
    # ret2 = []
    # print('---------------------')
    # for num in range(len(retList)):
    #     print(retList[num])
    #
    #     ret2.append(fields)
    #     # print(ret2)

    aaaalist = json.dumps(macdlist, ensure_ascii=False)
    # print(aaaalist)

    # return render(request, 'chartstest/public.html', {"dataList": data_list})
    return render(request, 'chartstest/macdDetails.html', {"detailList": json.dumps(data_list, ensure_ascii=False),
                                                       "macdlist": aaaalist})



# 在处理函数加此装饰器即可
@csrf_exempt
def delDate(request):
    tscode = request.POST['tscode']

    tusharDates = TusharDate.objects.filter(tscode=tscode)
    #print(tusharDates)

    for obj in tusharDates:
         url = str(obj.id)+".csv"
         if os.path.isfile(url):
            os.remove(url)
         print(obj.id)

    DealDetail.objects.filter(tscode=tscode).delete()

    TusharDate.objects.filter(tscode=tscode).delete()
    # ret = models.TusharDate.objects.all().order_by("dayIncome", "id")


    data = {'status': 0, 'message': '删除成功！'}
    return HttpResponse(json.dumps(data, ensure_ascii=False), content_type="application/json,charset=utf-8")
